package com.ggb.reactive.controller.admin

import com.ggb.reactive.constant.ACTION_FAIL
import com.ggb.reactive.constant.ENABLE
import com.ggb.reactive.constant.USER_ID
import com.ggb.reactive.domain.dto.CategoryDTO
import com.ggb.reactive.domain.dto.CategoryPageQueryDTO
import com.ggb.reactive.domain.entity.Category
import com.ggb.reactive.model.PageResult
import com.ggb.reactive.model.Result
import com.ggb.reactive.repository.CategoryRepository
import com.ggb.reactive.service.CategoryService
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import lombok.RequiredArgsConstructor
import org.springframework.beans.BeanUtils
import org.springframework.web.bind.annotation.*
import org.springframework.web.server.adapter.DefaultServerWebExchange
import reactor.core.publisher.Mono
import java.time.Instant

@RequestMapping("/admin/category")
@RestController
@RequiredArgsConstructor
@Tag(name = "分类管理")
class CategoryController(
    val categoryRepository: CategoryRepository,
    val categoryService: CategoryService
) {


    /**
     * 新增分类
     */
    @Operation(summary = "新增分类")
    @PostMapping
    fun add(@RequestBody categoryDTO: CategoryDTO, exchange: DefaultServerWebExchange): Mono<Result<String>> {
        val userId = (exchange.attributes[USER_ID] as Int).toLong()
        val category = Category(
            createTime = Instant.now(),
            updateTime = Instant.now(),
            createUser = userId,
            updateUser = userId,
        )
        BeanUtils.copyProperties(categoryDTO, category)
        category.status = ENABLE
        return categoryRepository.save(category).flatMap {
            Mono.just(Result.success<String>())
        }.onErrorResume {
            println(it)
            Mono.just(Result.error(ACTION_FAIL))
        }
    }

    /**
     * 更新分类
     */
    @Operation(summary = "更新分类")
    @PutMapping
    fun update(@RequestBody categoryDTO: CategoryDTO, exchange: DefaultServerWebExchange): Mono<Result<String>> {
        val userId = (exchange.attributes[USER_ID] as Int).toLong()
        return categoryRepository.findById(categoryDTO.id!!)
            .flatMap { category ->
                // 然后设置updateTime和updateUser
                category.apply {
                    updateTime = Instant.now()
                    updateUser = userId
                    name = categoryDTO.name
                    sort = categoryDTO.sort
                }
                // 保存更新后的实体
                categoryRepository.save(category)
            }
            .map {
                // 在保存操作完成后返回成功的结果
                Result.success<String>()
            }
            .onErrorResume {
                // 错误处理
                Mono.just(Result.error(ACTION_FAIL))
            }
    }

    /**
     * 分页查询
     */
    @Operation(summary = "分类分页查询")
    @GetMapping("/page")
    fun page(categoryPageQueryDTO: CategoryPageQueryDTO): Mono<Result<PageResult<Category>>> =
        categoryService.findCategoriesByCriteria(categoryPageQueryDTO)

    //{
    //   return categoryService.findCategoriesByCriteria(categoryPageQueryDTO)
    //// 假设EmployeePageQueryDTO中有页码和每页大小
    //val pageRequest = PageRequest.of(categoryPageQueryDTO.page - 1, categoryPageQueryDTO.pageSize)
    //
    //return categoryRepository.findCategoriesByOptionalCriteria(
    //    categoryPageQueryDTO.name,
    //    categoryPageQueryDTO.type
    //).collectList().map { categories ->
    //    // 根据分页参数手动实现分页逻辑
    //    val start = pageRequest.offset.toInt()
    //    val end = (start + pageRequest.pageSize).coerceAtMost(categories.size)
    //    val pageContent = if (start <= end) categories.subList(start, end) else listOf()
    //
    //    PageImpl(pageContent, pageRequest, categories.size.toLong())
    //}
    //    .map { page ->
    //        // 将Page<User>转换为你的PageResult<User>（假设你有一个类似的结构）
    //        Result.success(PageResult(total = page.totalElements, records = page.content))
    //    }
    //}

    /**
     * 启用、禁用分类
     */
    @Operation(summary = "启用、禁用分类")
    @PostMapping("/status/{status}")
    fun status(@PathVariable status: Int?, id: Long?, exchange: DefaultServerWebExchange): Mono<Result<String>> {
        //val user = User(id=id,status = status)
        //return myUserRepository.save(user)
        if (id == null) return Mono.just(Result.error("id名不能为空"))
        if (status == null) return Mono.just(Result.error("status不能为空"))
        val userId = (exchange.attributes[USER_ID] as Int).toLong()
        return categoryRepository.updateStatusById(id, status, Instant.now(), userId)
            .map {
                Result.success<String>()
            }
            .onErrorResume {
                Mono.just(Result.error(ACTION_FAIL))
            }
    }

    /**
     * 根据类型查询分类
     */
    @Operation(summary = "根据类型查询分类")
    @GetMapping("/list")
    fun list(type: Int): Mono<Result<List<Category>>> {

        return categoryRepository.findAllByType(type).collectList().map {
            Result.success(it)
        }
    }

    /**
     * 删除分类
     */
    @DeleteMapping
    @Operation(summary = "删除分类")
    fun deleteById(id: Long): Mono<Result<String>> {

        /**
         * deleteById方法在Reactive Repository中是一个无返回值的操作（Mono<Void>），这意味着它只表示操作的完成状态，而不携带任何数据。
         */
        return categoryRepository.deleteById(id)
            .then(Mono.just(Result.success<String>()))
            .onErrorResume {
                Mono.just(Result.error(ACTION_FAIL))
            }
    }

}